﻿#include "TextExpander.h"
#include <vtkTable.h>
#include <vtkDoubleArray.h>
#include <vtkAbstractArray.h>
#include <vtkVariantArray.h>
#include "TextArrayMetaHander.h"
#include <qmath.h>
#include <vtkFieldData.h>
#include <vtkStringArray.h>
#include <vtkDelimitedTextWriter.h>
#include <QVector>
#include <QSet>
#include <QDebug>

namespace pst
{
    TextExpander::TextExpander(QObject* parent)
        : QObject(parent)
        , m_originalTable{ nullptr }
        , m_expandedTable{ vtkTable::New() }
        , m_fileDealType{ -1 }
        , m_fileComponentType{ -1 }
    {
    }

    TextExpander::~TextExpander()
    {
        m_expandedTable->Delete();
    }

    void TextExpander::setInputTable(vtkTable* table)
    {
        m_originalTable = table;
    }

    vtkTable* TextExpander::getInputTable()
    {
        return m_originalTable;
    }

    bool TextExpander::update()
    {
        if (m_originalTable == nullptr)
        {
            return false;
        }

        QString filename = "name";
        int numCols = m_originalTable->GetNumberOfColumns();
        m_expandedTable->RemoveAllColumns();
        m_expandedTable->DeepCopy(m_originalTable);

        for (int i = 0; i < numCols; ++i)
        {
            auto array = vtkDoubleArray::SafeDownCast(m_expandedTable->GetColumn(i));
            if (array == nullptr)
            {
                return false;
            }
            TextArrayMetaStruct metaStruct;
            TextArrayMetaHander::getArrayMeta(array, metaStruct);
            // 如果是key列或者是标量列，则不需要扩展
            if (metaStruct.keyValueType == 0 || metaStruct.resultDataType == 4)
            {
                continue;
            }
            switch (metaStruct.resultDataType)
            {
                // 实部虚部幅度相位，四个中，只要有一个是-1，则需要扩展，并且一次性扩展全部
            case 0:                                       // 当前列为实部
                if (metaStruct.relatedMagPartIndex == -1) // 没有幅度列，即没有扩展过
                {
                    auto realArray = array;
                    auto imgArray = vtkDoubleArray::SafeDownCast(m_expandedTable->GetColumn(metaStruct.relatedImagPartIndex));

                    QString amplitudeUniit = "none";
                    QString phaseUnit = "none";
                    if (metaStruct.resultParaType == 0)
                    {
                        amplitudeUniit = "V/m";
                        phaseUnit = "deg";
                    }
                    else if (metaStruct.resultParaType == 1)
                    {
                        amplitudeUniit = "V";
                        phaseUnit = "deg";
                    }
                    else if (metaStruct.resultParaType == 8)
                    {
                        phaseUnit = "deg";
                    }

                    vtkNew<vtkDoubleArray> _magArray;
                    vtkNew<vtkDoubleArray> _phaseArray;
                    QString magName = "mag(" + metaStruct.dataGroupName + ")" + "||" + amplitudeUniit + "||value";
                    QString phaseName = "phase(" + metaStruct.dataGroupName + ")" + "||" + phaseUnit + "||value";
                    _magArray->SetName(magName.toUtf8().constData());
                    _phaseArray->SetName(phaseName.toUtf8().constData());

                    for (int j = 0; j < realArray->GetNumberOfTuples(); ++j)
                    {
                        auto realValue = realArray->GetValue(j);
                        auto imgValue = imgArray->GetValue(j);

                        double r = qSqrt(realValue * realValue + imgValue * imgValue); // 计算幅度
                        double theta = qAtan2(imgValue, realValue) / M_PI * 180;                 // 计算相位，使用 atan2 自动考虑 a 为负数的情况

                        _magArray->InsertNextValue(r);
                        _phaseArray->InsertNextValue(theta);
                    }
                    m_expandedTable->AddColumn(_magArray);
                    m_expandedTable->AddColumn(_phaseArray);

                    int _magArrayIndex = m_expandedTable->GetNumberOfColumns() - 2;
                    int _phaseArrayIndex = m_expandedTable->GetNumberOfColumns() - 1;

                    // 实部的meta
                    TextArrayMetaStruct metaStructReal = metaStruct;
                    metaStructReal.relatedMagPartIndex = _magArrayIndex;
                    metaStructReal.relatedPhasePartIndex = _phaseArrayIndex;
                    TextArrayMetaHander::setArrayMeta(realArray, metaStructReal);

                    // 虚部的meta
                    TextArrayMetaStruct metaStructImg;
                    TextArrayMetaHander::getArrayMeta(imgArray, metaStructImg);
                    metaStructImg.relatedMagPartIndex = _magArrayIndex;
                    metaStructImg.relatedPhasePartIndex = _phaseArrayIndex;
                    TextArrayMetaHander::setArrayMeta(imgArray, metaStructImg);

                    // 幅度的meta
                    TextArrayMetaStruct metaStructMag = metaStruct;
                    metaStructMag.resultDataType = 2; // 设置为幅度
                    metaStructMag.relatedMagPartIndex = _magArrayIndex;
                    metaStructMag.relatedPhasePartIndex = _phaseArrayIndex;
                    metaStructMag.unit = amplitudeUniit;
                    TextArrayMetaHander::setArrayMeta(_magArray, metaStructMag);

                    // 相位的meta
                    TextArrayMetaStruct metaStructPhase = metaStruct;
                    metaStructPhase.resultDataType = 3; // 设置为幅度
                    metaStructPhase.relatedMagPartIndex = _magArrayIndex;
                    metaStructPhase.relatedPhasePartIndex = _phaseArrayIndex;
                    metaStructPhase.unit = phaseUnit;
                    TextArrayMetaHander::setArrayMeta(_phaseArray, metaStructPhase);

                    filename = metaStructReal.fileName;

                    metaStruct.relatedMagPartIndex = _magArrayIndex;
                    metaStruct.relatedPhasePartIndex = _phaseArrayIndex;
                }
                break;

            case 1:                                       // 当前列为虚部
                if (metaStruct.relatedMagPartIndex == -1) // 没有幅度列，即没有扩展过
                {
                    auto imgArray = array;
                    auto realArray = vtkDoubleArray::SafeDownCast(m_expandedTable->GetColumn(metaStruct.relatedRealPartIndex));

                    QString amplitudeUniit = "none";
                    QString phaseUnit = "none";
                    if (metaStruct.resultParaType == 0)
                    {
                        amplitudeUniit = "V/m";
                        phaseUnit = "deg";
                    }
                    else if (metaStruct.resultParaType == 1)
                    {
                        amplitudeUniit = "V";
                        phaseUnit = "deg";
                    }
                    else if (metaStruct.resultParaType == 8)
                    {
                        phaseUnit = "deg";
                    }

                    vtkNew<vtkDoubleArray> _magArray;
                    vtkNew<vtkDoubleArray> _phaseArray;
                    QString magName = "mag(" + metaStruct.dataGroupName + ")" + "||" + amplitudeUniit + "||value";
                    QString phaseName = "phase(" + metaStruct.dataGroupName + ")" + "||" + phaseUnit + "||value";
                    _magArray->SetName(magName.toUtf8().constData());
                    _phaseArray->SetName(phaseName.toUtf8().constData());

                    for (int j = 0; j < realArray->GetNumberOfTuples(); ++j)
                    {
                        auto realValue = realArray->GetValue(j);
                        auto imgValue = imgArray->GetValue(j);

                        double r = qSqrt(realValue * realValue + imgValue * imgValue); // 计算幅度
                        double theta = qAtan2(imgValue, realValue) / M_PI * 180;                    // 计算相位，使用 atan2 自动考虑 a 为负数的情况

                        _magArray->InsertNextValue(r);
                        _phaseArray->InsertNextValue(theta);
                    }
                    m_expandedTable->AddColumn(_magArray);
                    m_expandedTable->AddColumn(_phaseArray);

                    int _magArrayIndex = m_expandedTable->GetNumberOfColumns() - 2;
                    int _phaseArrayIndex = m_expandedTable->GetNumberOfColumns() - 1;

                    // 实的meta
                    TextArrayMetaStruct metaStructReal;
                    TextArrayMetaHander::getArrayMeta(realArray, metaStructReal);
                    metaStructReal.relatedMagPartIndex = _magArrayIndex;
                    metaStructReal.relatedPhasePartIndex = _phaseArrayIndex;
                    TextArrayMetaHander::setArrayMeta(realArray, metaStructReal);

                    // 虚部的meta
                    metaStruct.relatedMagPartIndex = _magArrayIndex;
                    metaStruct.relatedPhasePartIndex = _phaseArrayIndex;
                    TextArrayMetaHander::setArrayMeta(imgArray, metaStruct);

                    // 幅度的meta
                    TextArrayMetaStruct metaStructMag = metaStruct;
                    metaStructMag.resultDataType = 2; // 设置为幅度
                    metaStructMag.relatedMagPartIndex = _magArrayIndex;
                    metaStructMag.relatedPhasePartIndex = _phaseArrayIndex;
                    metaStructMag.unit = amplitudeUniit;
                    TextArrayMetaHander::setArrayMeta(_magArray, metaStructMag);

                    // 相位的meta
                    TextArrayMetaStruct metaStructPhase = metaStruct;
                    metaStructPhase.resultDataType = 3; // 设置为相位
                    metaStructPhase.relatedMagPartIndex = _magArrayIndex;
                    metaStructPhase.relatedPhasePartIndex = _phaseArrayIndex;
                    metaStructPhase.unit = phaseUnit;
                    TextArrayMetaHander::setArrayMeta(_phaseArray, metaStructPhase);

                    filename = metaStructReal.fileName;

                    metaStruct.relatedMagPartIndex = _magArrayIndex;
                    metaStruct.relatedPhasePartIndex = _phaseArrayIndex;
                }
                break;

            case 2:                                        // 当前列为幅度
                if (metaStruct.relatedRealPartIndex == -1) // 没有实部列，即没有扩展过
                {
                    auto magArray = array;
                    auto phaseArray = vtkDoubleArray::SafeDownCast(m_expandedTable->GetColumn(metaStruct.relatedPhasePartIndex));

                    vtkNew<vtkDoubleArray> _realArray;
                    vtkNew<vtkDoubleArray> _imgArray;
                    QString realName = "real(" + metaStruct.dataGroupName + ")" + "||" + "none" + "||value";
                    QString imgName = "img(" + metaStruct.dataGroupName + ")" + "||" + "none" + "||value";
                    _realArray->SetName(realName.toUtf8().constData());
                    _imgArray->SetName(imgName.toUtf8().constData());

                    for (int j = 0; j < magArray->GetNumberOfTuples(); ++j)
                    {
                        auto magValue = magArray->GetValue(j);
                        auto phaseValue = phaseArray->GetValue(j);

                        auto realValue = magValue * qCos(phaseValue);
                        auto imgValue = magValue * qSin(phaseValue);

                        _realArray->InsertNextValue(realValue);
                        _imgArray->InsertNextValue(imgValue);
                    }

                    m_expandedTable->AddColumn(_realArray);
                    m_expandedTable->AddColumn(_imgArray);

                    int _realArrayIndex = m_expandedTable->GetNumberOfColumns() - 2;
                    int _imgArrayIndex = m_expandedTable->GetNumberOfColumns() - 1;

                    // 实的meta
                    TextArrayMetaStruct metaStructReal = metaStruct;
                    metaStructReal.resultDataType = 0; // 设置为实部
                    metaStructReal.relatedRealPartIndex = _realArrayIndex;
                    metaStructReal.relatedImagPartIndex = _imgArrayIndex;
                    metaStructReal.unit = "none";
                    TextArrayMetaHander::setArrayMeta(_realArray, metaStructReal);

                    // 虚部的meta
                    TextArrayMetaStruct metaStructImg = metaStruct;
                    metaStructImg.resultDataType = 1; // 设置为虚部
                    metaStructImg.relatedRealPartIndex = _realArrayIndex;
                    metaStructImg.relatedImagPartIndex = _imgArrayIndex;
                    metaStructImg.unit = "none";
                    TextArrayMetaHander::setArrayMeta(_imgArray, metaStructImg);

                    // 幅度的meta
                    TextArrayMetaStruct metaStructMag = metaStruct;
                    metaStructMag.relatedRealPartIndex = _realArrayIndex;
                    metaStructMag.relatedImagPartIndex = _imgArrayIndex;
                    TextArrayMetaHander::setArrayMeta(magArray, metaStructMag);

                    // 相位的meta
                    TextArrayMetaStruct metaStructPhase;
                    TextArrayMetaHander::getArrayMeta(phaseArray, metaStructPhase);
                    metaStructPhase.relatedRealPartIndex = _realArrayIndex;
                    metaStructPhase.relatedImagPartIndex = _imgArrayIndex;
                    TextArrayMetaHander::setArrayMeta(phaseArray, metaStructPhase);

                    filename = metaStructReal.fileName;

                    metaStruct.relatedRealPartIndex = _realArrayIndex;
                    metaStruct.relatedImagPartIndex = _imgArrayIndex;
                }
                break;

            case 3:                                        // 当前列为相位
                if (metaStruct.relatedRealPartIndex == -1) // 没有实部列，即没有扩展过
                {
                    auto phaseArray = array;
                    auto magArray = vtkDoubleArray::SafeDownCast(m_expandedTable->GetColumn(metaStruct.relatedMagPartIndex));

                    vtkNew<vtkDoubleArray> _realArray;
                    vtkNew<vtkDoubleArray> _imgArray;
                    QString realName = "real(" + metaStruct.dataGroupName + ")" + "||" + "none" + "||value";
                    QString imgName = "img(" + metaStruct.dataGroupName + ")" + "||" + "none" + "||value";
                    _realArray->SetName(realName.toUtf8().constData());
                    _imgArray->SetName(imgName.toUtf8().constData());

                    for (int j = 0; j < magArray->GetNumberOfTuples(); ++j)
                    {
                        auto magValue = magArray->GetValue(j);
                        auto phaseValue = phaseArray->GetValue(j);

                        auto realValue = magValue * qCos(phaseValue);
                        auto imgValue = magValue * qSin(phaseValue);

                        _realArray->InsertNextValue(realValue);
                        _imgArray->InsertNextValue(imgValue);
                    }

                    m_expandedTable->AddColumn(_realArray);
                    m_expandedTable->AddColumn(_imgArray);

                    int _realArrayIndex = m_expandedTable->GetNumberOfColumns() - 2;
                    int _imgArrayIndex = m_expandedTable->GetNumberOfColumns() - 1;

                    // 实的meta
                    TextArrayMetaStruct metaStructReal = metaStruct;
                    metaStructReal.resultDataType = 0; // 设置为实部
                    metaStructReal.relatedRealPartIndex = _realArrayIndex;
                    metaStructReal.relatedImagPartIndex = _imgArrayIndex;
                    metaStructReal.unit = "none";
                    TextArrayMetaHander::setArrayMeta(_realArray, metaStructReal);

                    // 虚部的meta
                    TextArrayMetaStruct metaStructImg = metaStruct;
                    metaStructImg.resultDataType = 1; // 设置为虚部
                    metaStructImg.relatedRealPartIndex = _realArrayIndex;
                    metaStructImg.relatedImagPartIndex = _imgArrayIndex;
                    metaStructImg.unit = "none";
                    TextArrayMetaHander::setArrayMeta(_imgArray, metaStructImg);

                    // 幅度的meta
                    TextArrayMetaStruct metaStructMag;
                    TextArrayMetaHander::getArrayMeta(magArray, metaStructMag);
                    metaStructMag.relatedRealPartIndex = _realArrayIndex;
                    metaStructMag.relatedImagPartIndex = _imgArrayIndex;
                    TextArrayMetaHander::setArrayMeta(magArray, metaStructMag);

                    // 相位的meta
                    TextArrayMetaStruct metaStructPhase = metaStruct;
                    TextArrayMetaHander::getArrayMeta(phaseArray, metaStructPhase);
                    metaStructPhase.relatedRealPartIndex = _realArrayIndex;
                    metaStructPhase.relatedImagPartIndex = _imgArrayIndex;
                    TextArrayMetaHander::setArrayMeta(phaseArray, metaStructPhase);

                    filename = metaStructReal.fileName;

                    metaStruct.relatedRealPartIndex = _realArrayIndex;
                    metaStruct.relatedImagPartIndex = _imgArrayIndex;
                }
                break;

            default:
                break;
            }
        }

        // 添加总幅度列
        if (m_fileDealType == 0 || m_fileDealType == 1 || m_fileDealType == 2)
        {
            addComponentTypeTotalColumn();
            addScalarTypeTotalColumn();
        }

        //#ifdef _DEBUG
        //        QString _name = "D:/expandedTable/" + filename + ".txt";
        //        vtkNew<vtkDelimitedTextWriter> writer;
        //        writer->SetInputData(m_expandedTable);
        //        writer->SetFileName(_name.toUtf8().constData());
        //        writer->Write();
        //#endif

        return true;
    }

    vtkTable* TextExpander::getExpandedTable()
    {
        return m_expandedTable;
    }

    void TextExpander::setFileDealType(int type)
    {
        m_fileDealType = type;
    }

    int TextExpander::getFileDealType()
    {
        return m_fileDealType;
    }

    void TextExpander::setFileComponentType(int type)
    {
        m_fileComponentType = type;
    }

    int TextExpander::getFileComponentType()
    {
        return m_fileComponentType;
    }

    void TextExpander::addComponentTypeTotalColumn()
    {
        auto colNum = m_expandedTable->GetNumberOfColumns();
        //根据需求，只需要找三列幅度计算平方和
        vtkNew<vtkDoubleArray> totalArray;


        QVector<vtkDoubleArray*> magArrayList;
        for (int i = 0; i < colNum; ++i)
        {
            auto array = vtkDoubleArray::SafeDownCast(m_expandedTable->GetColumn(i));
            if (array == nullptr)
            {
                continue;
            }
            TextArrayMetaStruct metaStruct;
            TextArrayMetaHander::getArrayMeta(array, metaStruct);
            if (metaStruct.resultDataType == 2) // 幅度
            {
                magArrayList.append(array);
            }
        }
        if (magArrayList.empty())
        {
            return;
        }

        if (magArrayList.size() != 3)
        {
            qDebug() << "Error: The number of magnitude columns is not 3, cannot calculate Etotal.";
            return;
        }
        for (int i = 0; i < magArrayList[0]->GetNumberOfTuples(); ++i)
        {
            double totalValue = 0.0;
            for (const auto& magArray : magArrayList)
            {
                totalValue += magArray->GetValue(i) * magArray->GetValue(i);
            }
            totalArray->InsertNextValue(qSqrt(totalValue)); // 计算平方根
        }

        m_expandedTable->AddColumn(totalArray);
        // 设置meta信息
        TextArrayMetaStruct totalMeta;
        TextArrayMetaHander::getArrayMeta(magArrayList[0], totalMeta);
        totalMeta.dataGroupName = "E_total";
        totalMeta.resultDataType = 4; // 设置为标量
        totalMeta.relatedScalarIndex = colNum; // 新列的索引
        //单位和幅度列单位保持一致
        TextArrayMetaHander::setArrayMeta(totalArray, totalMeta);

        QString colName = "E_total||" + totalMeta.unit + " || value";
        totalArray->SetName(colName.toUtf8().constData());
    }

    void TextExpander::addScalarTypeTotalColumn()
    {
        //012类型：判断value列 总共只有三列，并且都是标量，则计算Etotal （添加规则by周行 2025.08.18）
        auto colNum = m_expandedTable->GetNumberOfColumns();
        //根据需求，只需要找三列幅度计算平方和
        vtkNew<vtkDoubleArray> totalArray;

        QVector<vtkDoubleArray*> valueArrayList;//value列
        QVector<vtkDoubleArray*> valueScalarArrayList;//value列 并且是标量
        for (int i = 0; i < colNum; ++i)
        {
            auto array = vtkDoubleArray::SafeDownCast(m_expandedTable->GetColumn(i));
            if (array == nullptr)
            {
                continue;
            }
            TextArrayMetaStruct metaStruct;
            TextArrayMetaHander::getArrayMeta(array, metaStruct);
            if (metaStruct.keyValueType == 1) // value列
            {
                valueArrayList.append(array);
                if (metaStruct.relatedScalarIndex != -1)
                {
                    valueScalarArrayList.append(array);//value列 并且是标量
                }
            }
        }

        if (valueArrayList.size() == valueScalarArrayList.size() && valueArrayList.size() == 3)//判断value列 总共只有三列，并且都是标量，则计算Etotal
        {
            for (int i = 0; i < valueArrayList[0]->GetNumberOfTuples(); ++i)
            {
                double totalValue = 0.0;
                for (const auto& magArray : valueArrayList)
                {
                    totalValue += magArray->GetValue(i) * magArray->GetValue(i);
                }
                totalArray->InsertNextValue(qSqrt(totalValue)); // 计算平方根
            }

            m_expandedTable->AddColumn(totalArray);
            // 设置meta信息
            TextArrayMetaStruct totalMeta;
            TextArrayMetaHander::getArrayMeta(valueArrayList[0], totalMeta);
            totalMeta.dataGroupName = "E_total";
            totalMeta.resultDataType = 4; // 设置为标量
            totalMeta.relatedScalarIndex = colNum; // 新列的索引
            //单位和幅度列单位保持一致
            TextArrayMetaHander::setArrayMeta(totalArray, totalMeta);

            QString colName = "E_total||" + totalMeta.unit + " || value";
            totalArray->SetName(colName.toUtf8().constData());
        }
    }
} // namespace pst
